package com.sp.fresh_produce.service.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.sp.fresh_produce.controller.dto.VO.CategoryVORequest;
import com.sp.fresh_produce.ex.CustomException;
import com.sp.fresh_produce.ex.ExceptionCodeEnum;
import com.sp.fresh_produce.model.dao.CategoryMapper;
import com.sp.fresh_produce.model.pojo.Category;
import com.sp.fresh_produce.service.CategoryService;
import com.sp.fresh_produce.util.PageUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.List;

/**
 * 分类领域服务实现
 * <p>
 * 负责分类的新增、删除、分页查询与前台分类树构建等逻辑。
 */
@Service
public class CategoryServiceImpl implements CategoryService {
    @Autowired
    private CategoryMapper categoryMapper;

    /**
     * 添加分类
     *
     * @param category 分类
     * @return 添加结果
     */
    @Override
    public int addCategory(Category category) {
        // 基础参数校验：分类名称不能为空
        if (category == null || category.getName() == null || category.getName().trim().isEmpty()) {
            throw new CustomException(ExceptionCodeEnum.PARAMS_ERROR.getCode(), ExceptionCodeEnum.PARAMS_ERROR.getMessage());
        }
        // 归一化名称后做唯一性检查
        String name = category.getName().trim();
        Category exists = categoryMapper.selectByName(name);
        if (exists != null) {
            throw new CustomException(ExceptionCodeEnum.PARAMS_ERROR.getCode(), ExceptionCodeEnum.PARAMS_ERROR.getMessage());
        }
        // 设置规范化名称后落库（insertSelective 仅插入非空字段）
        category.setName(name);
        return categoryMapper.insertSelective(category);
    }

    /**
     * 删除分类
     *
     * @param id 分类ID
     * @return 删除结果
     */
    @Override
    public int deleteCategory(Integer id) {
        // 基础参数校验：分类 ID 不能为空
        if (id == null) {
            throw new CustomException(ExceptionCodeEnum.PARAMS_ERROR.getCode(), ExceptionCodeEnum.PARAMS_ERROR.getMessage());
        }
        // 校验分类是否存在
        Category category = categoryMapper.selectByPrimaryKey(id);
        if (category == null) {
            throw new CustomException(ExceptionCodeEnum.NOT_FOUND.getCode(), ExceptionCodeEnum.NOT_FOUND.getMessage());
        }
        // 执行删除并返回结果
        return categoryMapper.deleteByPrimaryKey(id);
    }

    /**
     * 分页查询分类
     *
     * @param pageNum  页码
     * @param pageSize 每页数量
     * @return 分类分页结果
     */
    @Override
    public PageInfo<Category> getCategoryList(Integer pageNum, Integer pageSize) {
        // 使用工具类规范化分页参数
        int[] pageParams = PageUtil.normalizePagination(pageNum, pageSize);
        int safePageNum = pageParams[0];
        int safePageSize = pageParams[1];
        
        // 启动分页插件（PageHelper）
        PageHelper.startPage(safePageNum, safePageSize);
        
        // 查询数据
        int offset = PageUtil.calculateOffset(safePageNum, safePageSize);
        List<Category> categories = categoryMapper.selectCategoryPage(offset, safePageSize);
        int total = categoryMapper.countCategoryAll();
        
        // 使用工具类构建分页信息
        return PageUtil.buildPageInfo(categories, total, safePageNum, safePageSize);
    }

    /**
     * 获取用于前台展示的分类树
     */
    @Cacheable(cacheNames = "categoryListForUser", key = "#parentId == null ? 'root' : #parentId", unless = "#result == null || #result.isEmpty()")
    @Override
    public List<CategoryVORequest> getCategoryListForUser(Integer parentId) {
        // 1) 初始化返回列表
        List<CategoryVORequest> categoryList = new ArrayList<>();
        // 2) 从根节点开始递归构建分类树（根的 parentId 约定为 0）
        // 如果 parentId 为 null，则默认从根节点（parentId = 0）开始
        recursionFindCategories(parentId == null ? 0 : parentId, categoryList);
        return categoryList;
    }

    /**
     * 递归查找分类列表
     *
     * @param parentId     父级分类ID
     * @param categoryList 分类列表
     */
    /**
     * 递归构建分类树
     *
     * @param parentId     父级分类 ID
     * @param categoryList 输出的子分类列表
     */
    private void recursionFindCategories(int parentId, List<CategoryVORequest> categoryList) {
        // 查询当前父级下的直接子分类
        List<Category> categories = categoryMapper.selectCategoryByParentId(parentId);
        if (!CollectionUtils.isEmpty(categories)) {
            for (int i = 0; i < categories.size(); i++) {
                CategoryVORequest categoryVO = new CategoryVORequest();
                Category category = categories.get(i);
                // 将实体属性拷贝至 VO
                BeanUtils.copyProperties(category, categoryVO);
                categoryList.add(categoryVO);
                // 递归填充子分类列表
                recursionFindCategories(category.getId(), categoryVO.getChildren());
            }
        }

    }
}
